package bjut.zrpc.core.optimization.compress;

import bjut.zrpc.core.optimization.interfaces.Compress;
import lombok.SneakyThrows;
import org.xerial.snappy.SnappyInputStream;
import org.xerial.snappy.SnappyOutputStream;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

/**
 * @Author: zhuzhiming
 * @Date: 2022/6/26 19:44
 */
public class SnappyCompress implements Compress {

    private final int BLOCK = 1024 * 1024 * 8;

    @SneakyThrows
    @Override
    public byte[] compress(byte[] data) {

        ByteArrayInputStream is = new ByteArrayInputStream(data);
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        SnappyOutputStream sos = new SnappyOutputStream(os);
        int count;
        byte temp[] = new byte[BLOCK];
        try {
            while ((count = is.read(temp)) != -1) {
                sos.write(temp, 0, count);
            }
            sos.flush();
            byte[] output = os.toByteArray();
            return output;
        } finally {
            sos.close();
            is.close();
        }

    }

    @SneakyThrows
    @Override
    public byte[] deCompress(byte[] data) {
        byte[] buffer = new byte[BLOCK];
        ByteArrayInputStream is = new ByteArrayInputStream(data);
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        SnappyInputStream sis = new SnappyInputStream(is);
        try {
            while (true) {
                int count = sis.read(buffer, 0, buffer.length);
                if (count == -1) {
                    break;
                }
                os.write(buffer, 0, count);
            }
            os.flush();
        } finally {
            try {
                sis.close();
                os.close();
                is.close();
            } catch (Exception exception) {
                throw new RuntimeException(exception.getMessage());
            }

        }
        return os.toByteArray();
    }
}
